package com.mo.tools.http;


import cn.hutool.extra.servlet.ServletUtil;
import com.mo.tools.verification.ObjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.util.ContentCachingRequestWrapper;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: Yang.Xingfu
 * @date: 2024/7/19 09:51
 */
public class RequestLogThreadLocal implements HandlerInterceptor {

    Logger log = LoggerFactory.getLogger(RequestLogThreadLocal.class);

    /**
     * 请求记录缓存
     */
    public static ThreadLocal<Map<?, ?>> REQUEST_LOG_TL = new InheritableThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String userId = null;
        String companyCode = null;
        try {
            HttpServletRequest cacheRequest = cacheHttpRequest(request);
            Map<String, Object> map = new HashMap<>();
            map.put("ip", ServletUtil.getClientIP(request));
            map.put("method", request.getMethod());
            String contextPath = request.getContextPath();
            contextPath = ObjectUtil.isEmpty(contextPath) ? "default" : contextPath;
            map.put("contextPath", contextPath);
            Map<String, String> headerMap = ServletUtil.getHeaderMap(cacheRequest);
            Map<String, String[]> params = ServletUtil.getParams(cacheRequest);
            String body = ServletUtil.getBody(cacheRequest);
        } catch (Exception e) {
            log.error("保存请求日志错误 公司编码 [{}] 请求用户id [{}] 请求路径 [{}] ", companyCode, userId, request.getRequestURI(), e);
        }
        return true;
    }

    /**
     * 包装已使用了
     *
     * @param request
     * @return
     */
    public HttpServletRequest cacheHttpRequest(HttpServletRequest request) {
        HttpServletRequest clonedRequest = new ContentCachingRequestWrapper(request) {
            @Override
            public ServletInputStream getInputStream() throws IOException {
                return new ServletInputStream() {
                    @Override
                    public boolean isFinished() {
                        return false;
                    }

                    @Override
                    public boolean isReady() {
                        return false;
                    }

                    @Override
                    public void setReadListener(ReadListener readListener) {

                    }

                    private final ByteArrayInputStream bais = new ByteArrayInputStream(getContentAsByteArray());

                    @Override
                    public int read() throws IOException {
                        return bais.read();
                    }

                };
            }

            @Override
            public BufferedReader getReader() throws IOException {
                return new BufferedReader(new InputStreamReader(getInputStream()));
            }
        };

        return clonedRequest;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        clear();
    }



    /**
     * 清除缓存
     */
    public static void clear() {
        REQUEST_LOG_TL.remove();
    }
}
